GSimpleAsyncResult *result;
} OstreeFetcherPendingURI;
+static void ostree_fetcher_pending_uri_done (OstreeFetcher *self,
+ OstreeFetcherPendingURI *pending);
+
static void
pending_uri_free (OstreeFetcherPendingURI *pending)
{
if (pending->refcount > 0)
return;
+ if (!pending->is_stream)
+ ostree_fetcher_pending_uri_done (pending->self, pending);
+
soup_uri_free (pending->uri);
g_clear_object (&pending->self);
g_clear_object (&pending->out_tmpfile);
guint64 total_downloaded;
guint total_requests;
+
+ /* Queue for libsoup, see bgo#708591 */
+ gint outstanding;
+ GQueue pending_queue;
+ gint max_outstanding;
};
G_DEFINE_TYPE (OstreeFetcher, ostree_fetcher, G_TYPE_OBJECT)
g_hash_table_destroy (self->sending_messages);
g_hash_table_destroy (self->message_to_request);
+ g_queue_clear (&self->pending_queue);
+
G_OBJECT_CLASS (ostree_fetcher_parent_class)->finalize (object);
}
static void
ostree_fetcher_init (OstreeFetcher *self)
{
+ gint max_conns;
+
+ g_queue_init (&self->pending_queue);
self->session = soup_session_async_new_with_options (SOUP_SESSION_USER_AGENT, "ostree ",
SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_REQUESTER,
NULL);
self->requester = (SoupRequester *)soup_session_get_feature (self->session, SOUP_TYPE_REQUESTER);
+ g_object_get (self->session, "max-conns-per-host", &max_conns, NULL);
+ self->max_outstanding = 3 * max_conns;
g_signal_connect (self->session, "request-started",
G_CALLBACK (on_request_started), self);
return self;
}
+static void
+on_request_sent (GObject *object, GAsyncResult *result, gpointer user_data);
+
+static void
+ostree_fetcher_pending_uri_done (OstreeFetcher *self,
+ OstreeFetcherPendingURI *pending)
+{
+ OstreeFetcherPendingURI *p;
+
+ g_assert (!pending->is_stream);
+
+ self->outstanding--;
+ p = g_queue_pop_head (&self->pending_queue);
+ if (p != NULL)
+ {
+ self->outstanding++;
+ soup_request_send_async (p->request, p->cancellable,
+ on_request_sent, p);
+ }
+}
+
+static void
+ostree_fetcher_queue_pending_uri (OstreeFetcher *self,
+ OstreeFetcherPendingURI *pending)
+{
+ g_assert (!pending->is_stream);
+
+ if (self->outstanding >= self->max_outstanding)
+ {
+ g_queue_push_tail (&self->pending_queue, pending);
+ }
+ else
+ {
+ self->outstanding++;
+ soup_request_send_async (pending->request, pending->cancellable,
+ on_request_sent, pending);
+ }
+}
+
+
+
static void
on_splice_complete (GObject *object,
GAsyncResult *result,
soup_request_http_get_message ((SoupRequestHTTP*)pending->request),
pending);
}
-
- soup_request_send_async (pending->request, cancellable,
- on_request_sent, pending);
+
+ ostree_fetcher_queue_pending_uri (self, pending);
out:
if (local_error != NULL)